package com.core.indexer;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

public class PRF {

	private HashMap<String, Double> mapTSV;
    private ValueComparator bvc;
    private TreeMap<String,Double> sorted_mapTSV;
    private HashMap<String, Double> map_rt;
    private HashMap<String, Double> map_ft;
    
	public static PRF Get()
	{
		if(mInstance == null)
		{
			mInstance = new PRF();
			
		}
		return mInstance;
	}
	
	public void CalculateTSV(String term, double R, double rt, double ft, double N)
	{
		if(mapTSV.containsKey(term))
			return;
		
		Double dTSV = new Double(Math.pow((ft/N), rt)*(Factorial(R)/(Factorial(rt))*(Factorial(R - rt))));
		mapTSV.put(term, dTSV);
		map_rt.put(term, rt);
		map_ft.put(term, ft);
	}
	
	public double GetRT(String term)
	{
		if(map_rt.containsKey(term))
			return map_rt.get(term);
		else
			return 0;
	}
	
	public double GetFT(String term)
	{
		if(map_ft.containsKey(term))
			return map_rt.get(term);
		else
			return 0;
	}
	
	public ArrayList<String> GetNewQuery(int aditionalQueryNum)
	{
		
		ArrayList<String> arrQuery = new ArrayList<String>();
		sorted_mapTSV.putAll(mapTSV);
				
		int nCount = 0;
		for(String key : sorted_mapTSV.descendingKeySet())
		{
			arrQuery.add(key);
			nCount++;
			if(nCount >= aditionalQueryNum)
				break;
		}
		return arrQuery;
	}
	
	public double GetWT(String term, double R, double N)
	{
		double rt = map_rt.get(term);
		double ft = map_ft.get(term);
		
		return GetWT(R, rt, ft, N);
	}
	
	public double GetWT(double R, double rt, double ft, double N)
	{
		return Math.log((rt + 0.5)*(N - ft - R + rt + 0.5)/(ft - rt + 0.5)*(R - rt + 0.5));
	}
	
    private double Factorial(double n) {
        double fact = 1; // this  will be the result
        for (int i = 1; i <= n; i++) {
            fact *= i;
        }
        return fact;
    }
    
	private static PRF mInstance = null;
	private PRF()
	{
		mapTSV = new HashMap<String, Double>();
		map_rt = new HashMap<String, Double>();
		map_ft = new HashMap<String, Double>();
		bvc =  new ValueComparator(mapTSV);
		sorted_mapTSV = new TreeMap<String,Double>(bvc);
	}
	
	class ValueComparator implements Comparator<String> {

	    Map<String, Double> base;
	    public ValueComparator(Map<String, Double> base) {
	        this.base = base;
	    }

	    // Note: this comparator imposes orderings that are inconsistent with equals.    
	    public int compare(String a, String b) {
	        if (base.get(a) >= base.get(b)) {
	            return -1;
	        } else {
	            return 1;
	        } // returning 0 would merge keys
	    }
	}
}
